<?php

namespace App\Models;

use Carbon\Carbon;

class Order extends Model
{
    protected $table = 'orders';

    const PAY_SURPLUS_MINUTES = 30; // 支付剩余分钟

    const ORDER_STATUS = [
        'need_pay' => 10, // 未支付
        'paid' => 20, // 已支付
        'canceled' => 30, // 已取消
        'refund' => 40, // 已退款
        'fail' => 50 // 支付失败
    ];

    protected static function boot()
    {
        parent::boot();
        // 监听模型创建事件，在写入数据库之前触发
        static::creating(function ($model) {
            if (!$model->getTradeNo()) {
                $tradeNo = static::getAvailableNo();
                if ($tradeNo) {
                    $model->setTradeNo($tradeNo);
                } else {
                    return false;
                }
            }
        });
    }


    // ============= relations ==========
    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }

    // ============= scope ==========
    public function scopeOfUserPaidOrder($query, $userId)
    {
        return $query->where('user_id', $userId)->where('status', static::ORDER_STATUS['paid']);
    }


    public function scopeOfTimeoutOrder($query)
    {
        return $query->where('status', static::ORDER_STATUS['need_pay'])->where('created_at', '<', Carbon::now()->subMinutes(static::PAY_SURPLUS_MINUTES));
    }

    // ============= field ==========

    public function getTradeNo()
    {
        return $this->trade_no;
    }

    public function setTradeNo($tradeNo)
    {
        $this->trade_no = $tradeNo;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setQuantity($quantity)
    {
        $this->quantity = $quantity;
    }

    public function getQuantity()
    {
        return $this->quantity;
    }

    public function setUserId($userId)
    {
        $this->user_id = $userId;
    }

    public function getUserId()
    {
        return $this->user_id;
    }

    public function setTotalAmount($amount)
    {
        $this->total_amount = $amount;
    }

    public function getTotalAmount()
    {
        return $this->total_amount;
    }


    public function setDiscountAmount($amount)
    {
        $this->discount_amount = $amount;
    }

    public function setActualAmount($amount)
    {
        $this->actual_amount = $amount;
    }

    public function getActualAmount()
    {
        return $this->actual_amount;
    }

    public function getPaidAmount()
    {
        return $this->paid_amount;
    }

    public function setPaidAmount($amount)
    {
        $this->paid_amount = $amount;
    }

    public function setWxTransactionId($transactionId)
    {
        $this->wx_transaction_id = $transactionId;
    }

    public function getStatus()
    {
        return $this->status;
    }

    public function setStatus($status)
    {
        $this->status = $status;
    }

    public function getCreatedAt()
    {
        return $this->created_at;
    }

    public function setPaidAt($time)
    {
        $this->paid_at = $time;
    }

    public function getPaidAt()
    {
        return $this->paid_at ? $this->paid_at : null;
    }

    // 未支付订单剩余时间
    public function getPaySurplusTime()
    {
        if ($this->status == static::ORDER_STATUS['need_pay']) {
            return max(30 - Carbon::now()->diffInMinutes($this->created_at), 0);
        } else {
            return 0;
        }
    }

    public function checkPayStatus()
    {
        if ($this->status != static::ORDER_STATUS['need_pay']) {
            return false;
        }
        if ((static::PAY_SURPLUS_MINUTES - Carbon::now()->diffInMinutes($this->created_at)) <= 0) {
            return false;
        }
        return true;
    }

    public function checkCancelStatus()
    {
        // 已支付和已退款的不能取消
        if ($this->status == static::ORDER_STATUS['paid'] || $this->status == static::ORDER_STATUS['refund']) {
            return false;
        }
        return true;
    }


    public static function getAvailableNo()
    {
        // 订单流水号前缀
        $prefix = 'A' . date('YmdHis');
        for ($i = 0; $i < 10; $i++) {
            // 随机生成 6 位的数字
            $no = $prefix . str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
            // 判断是否已经存在
            if (!static::query()->where('trade_no', $no)->exists()) {
                return $no;
            }
            usleep(100);
        }
        return false;
    }
}
